package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.article.mapper.ApArticleContentMapper;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.ArticleFreemarkerService;
import com.heima.common.constants.ArticleConstants;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.search.vos.SearchArticleVo;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.concurrent.ListenableFuture;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * @author shiminghui
 * @date 2024/11/10 16:43
 * @description: TODO
 */
@Service
@Slf4j
public class ArticleFreemarkerServiceImpl implements ArticleFreemarkerService {

    @Autowired
    private Configuration configuration;
    @Autowired
    private FileStorageService fileStorageService;
    @Autowired
    private ApArticleMapper apArticleMapper;
    @Autowired
    private KafkaTemplate kafkaTemplate;

    @Override
    @Async // 开启多线程
    public void buildArticleToMinIO(ApArticle apArticle, String content) {
        if (StringUtils.isBlank(content)) {
            log.error("构建静态资源失败,内容为空");
            return;
        }
        if (apArticle == null) {
            log.error("构建静态资源失败,文章为空");
            return;
        }
        // 1.生成静态文件
        StringWriter stringWriter = null;
        try {
            Template template = configuration.getTemplate("article.ftl");
            ArrayList list = JSON.parseObject(content, ArrayList.class);
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("content", list);
            stringWriter = new StringWriter();
            template.process(hashMap, stringWriter);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (TemplateException e) {
            throw new RuntimeException(e);
        }
        // 2.上传到minio
        String url = null;
        try {
            byte[] bytes = stringWriter.toString().getBytes("UTF-8");
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
            url = fileStorageService.uploadHtmlFile("", apArticle.getId() + ".html", bais);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }

        String staticUrl = apArticle.getStaticUrl();


        // 3.修改文章的url字段
        if (url != null && !url.isEmpty()) {
            int update = apArticleMapper.update(apArticle, Wrappers.lambdaUpdate(ApArticle.class).eq(ApArticle::getId, apArticle.getId()).set(ApArticle::getStaticUrl, url));
            if (update != 1) {
                log.error("修改文章的url字段失败");
            }
        }

        // 4.删除minio文件
        if (staticUrl != null && !staticUrl.isEmpty()) {
            fileStorageService.delete(staticUrl);
        }

        // 5.添加数据到es
        createArticleESIndex(apArticle, content, url);

    }

    /**
     * 添加数据到es中
     *
     * @param apArticle
     * @param content
     * @param url
     */
    private void createArticleESIndex(ApArticle apArticle, String content, String url) {
        SearchArticleVo vo = new SearchArticleVo();
        BeanUtils.copyProperties(apArticle, vo);
        vo.setContent(content);
        vo.setStaticUrl(url);

        ListenableFuture send = kafkaTemplate.send(ArticleConstants.ARTICLE_ES_SYNC_TOPIC, JSON.toJSONString(vo));
        send.addCallback(o -> log.info("添加数据到es成功(发送消息成功)"), throwable -> log.error("添加数据到es失败(发送消息失败)"));
    }
}
